package com.sinosoft.hydra.um.services.component.dataCollect;

import cn.com.sinux.spring.utils.DateUtils;
import cn.com.sinux.spring.utils.ValidatorUtils;
import com.sinosoft.hydra.logging.LogModules;
import com.sinosoft.hydra.um.constant.BaseConstant;
import com.sinosoft.hydra.um.services.component.dataCollect.readers.ReadUtils;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.util.*;

/**
 * Created by lcb on 2016/7/15.
 */
public class DataResult {

    private List<Label> labels = new ArrayList<Label>();

    public static class DataSet {
        private List<String> titles;
        private List<List<String>> data = new ArrayList<List<String>>();

        public List<String> getTitles() {
            return titles;
        }

        public void setTitles(List<String> titles) {
            this.titles = titles;
        }

        public void addData(List<String> data) {
            if (ValidatorUtils.isArrayNotEmpty(data))
                this.data.add(data);
        }

        public List<List<String>> getData() {
            return data;
        }
    }

    private DataSet excelData;
    private DataSet lineData;

    public DataSet getExcelData() {
        return excelData;
    }

    public DataSet getLineData() {
        return lineData;
    }

    public DataResult() {
        excelData = new DataSet();
        lineData = new DataSet();
    }

    public void addTitles(List<String> list, int total, DataParser parser) {
        excelData.setTitles(ReadUtils.doFiler(list, parser.getExcelDataCells(total)));
        lineData.setTitles(ReadUtils.doFiler(list, parser.getLineDataCells(total)));
    }

    public void addData(List<String> list, int total, DataParser parser) {
        excelData.addData(ReadUtils.doFiler(parser.rendExcelData(list), parser.getExcelDataCells(total)));
        lineData.addData(ReadUtils.doFiler(parser.rendLineData(list), parser.getLineDataCells(total)));
    }


    public static class Label {
        private String text;
        private String type;

        public void setText(String text) {
            this.text = text;
        }

        public Label(String text, BaseConstant.LabelType labelType) {
            this.text = text;
            this.type = labelType.name();
        }

        public String getText() {
            return text;
        }

        public String getType() {
            return type;
        }
    }

    public List<Label> getLabels() {
        return labels;
    }

    public static class TimeLineData {
        private Date time;
        private List<String> titles;
        private List<Double> doubles = new ArrayList<Double>();

        public List<Double> getDoubles() {
            return doubles;
        }

        public Date getTime() {
            return time;
        }

        public List<String> getTitles() {
            return titles;
        }

        public TimeLineData(List<String> cells, List<String> titles) {
            try {
                this.titles = titles.subList(1, titles.size());
                time = DateUtils.parseDate(cells.get(0), BaseConstant.timePatterns);
            } catch (ParseException e) {
                LoggerFactory.getLogger(LogModules.STD_LOGGER).error("日期格式转换失败{}", e.getMessage());
            }
            for (int i = 1; i < cells.size(); i++) {
                String cel = cells.get(i);
                Double result;
                if ("".equals(cel)) {
                    result = (double) 0;
                } else if (cel.contains("e") || cel.contains("E")) {
                    String e = cel.contains("e") ? "e" : "E";
                    String[] arr = cel.split(e);
                    result = Double.valueOf(arr[0]) * Math.pow(10, Double.valueOf(arr[1]));
                } else {
                    result = Double.valueOf(cel);
                }
                doubles.add(result);
            }


        }
    }

    public static class TitleLineData {
        private String title;
        private List<Date> times = new ArrayList<Date>();
        private List<Double> doubles = new ArrayList<Double>();

        public String getTitle() {
            return title;
        }

        public TitleLineData(String title) {
            this.title = title;
        }

        public List<Date> getTimes() {
            return times;
        }

        public void addValue(Date time, Double d) {
            this.times.add(time);
            doubles.add(d);
        }

        public List<Double> getDoubles() {
            return doubles;
        }
    }

    public List<TimeLineData> toTimeLineData() {
        List<TimeLineData> lineDatas = new ArrayList<TimeLineData>();
        for (List<String> cells : lineData.getData()) {
            lineDatas.add(new TimeLineData(cells, lineData.getTitles()));
        }
        Collections.sort(lineDatas, new Comparator<TimeLineData>() {

            public int compare(TimeLineData timeLineData, TimeLineData timeLineData2) {
                return timeLineData.getTime().compareTo(timeLineData2.getTime());
            }
        });
        return lineDatas;
    }

    public List<TitleLineData> toTitleLineData(List<TimeLineData> lineDatas) {
        if (lineDatas == null) {
            lineDatas = toTimeLineData();
        }
        List<TitleLineData> titleLineDatas = new ArrayList<TitleLineData>();
        List<String> titles = lineData.getTitles().subList(1, lineData.getTitles().size());
        for (String title : titles) {
            titleLineDatas.add(new TitleLineData(title));
        }
        for (TimeLineData timeLineData : lineDatas) {
            List<Double> doubles = timeLineData.getDoubles();
            Date time = timeLineData.getTime();
            for (int i = 0, l = doubles.size(); i < l; i++) {
                titleLineDatas.get(i).addValue(time, doubles.get(i));
            }
        }
        return titleLineDatas;
    }

    public void addLabel(String text, BaseConstant.LabelType labelType) {
        labels.add(new Label(text, labelType));
    }

    public void addLabels(List<Label> labels) {
        if (ValidatorUtils.isArrayNotEmpty(labels)) {
            this.labels.addAll(labels);
        }
    }
}
